<?php

namespace services\log;

use api\modules\v1\forms\patient\PatientForm;
use common\components\Service;
use common\helpers\CommonHelper;
use common\helpers\DateHelper;
use common\models\base\PatientDiseases;
use common\models\clinic\Clinic;
use common\models\log\MemberOperateLog;
use common\models\marketing\ClinicAssess;
use common\models\marketing\EffectType;
use common\models\marketing\OutpatientType;
use common\models\marketing\RiskType;
use common\models\marketing\SourceChannel;
use common\models\member\Member;
use common\models\patient\Callback;
use common\models\patient\User;
use Yii;
use yii\db\ActiveRecord;

class MemberOperateLogService extends Service
{
    /**
     * @param int $porjectId
     * @param int $patientId
     * @param int $actionType
     * @param string $content
     * @return MemberOperateLog
     * @throws \Exception
     */
    public static function create(int $relationId, string $content, int $type, int $memberId = 0): MemberOperateLog
    {
        $operateLog = new MemberOperateLog();
        $operateLog->relation_id = $relationId;
        if ($memberId) {// 接口操作，非脚本系统操作
            $operateLog->method = Yii::$app->request->method;
            $url = explode('?', Yii::$app->request->getUrl());
            $operateLog->url = $url[0];
            $operateLog->user_agent = CommonHelper::detectVersion();
            $ip = (int)ip2long(Yii::$app->request->userIP);
            $operateLog->ip = long2ip($ip);
        }
        $operateLog->type = $type;
        $operateLog->content = $content;
        $operateLog->member_id = $memberId;
        $operateLog->member_name = $memberId ? Member::findOne($memberId)->realname ?? '' : '系统';
        $operateLog->saveAndCheckResult();
        return $operateLog;
    }

    /**
     * 是否修改model
     * @param ActiveRecord $old
     * @param ActiveRecord $new
     * @param array $column
     * @return bool
     */
    public static function isEditModel(ActiveRecord $old, ActiveRecord $new, array $column = []): bool
    {
        if (empty($column)) {
            return false;
        }
        foreach ($column as $item) {
            if (is_string($old[$item]) || is_numeric($old[$item])) {
                $old[$item] = (string)$old[$item];
            }
            if (is_string($new[$item]) || is_numeric($new[$item])) {
                $new[$item] = (string)$new[$item];
            }
            if ($old[$item] !== $new[$item]) {
                return true;
            }
        }
        return false;
    }

    /**
     * 导医操作日志
     * @param string $scenario
     * @param User $new
     * @param User|null $old
     * @return MemberOperateLog|null
     * @throws \Exception
     */
    public static function createGuideLog(string $scenario, User $new, ?User $old = null): ?MemberOperateLog
    {
        $content = '';
        $type = 0;
        $relationId = 0;
        switch ($scenario) {
            case 'guide_craete':// 导医登记
                $type = MemberOperateLog::TYPE_PATIENT_GUIDE_CREATE;
                $gender = User::$genders[$new->gender] ?? '';
                $sourceName = $new->source_channel_id ? SourceChannel::findOne($new->source_channel_id)->source_name ?? '' : '';
                $clinicName = Clinic::findOne($new->clinic_id)->name ?? '';
                $belongAssistantName = Member::findOne($new->belong_assistant_id)->realname ?? '';
                $outpatientName = OutpatientType::findOne($new->outpatient_type_id)->outpatient_name ?? '';
                $regTime = DateHelper::timestampToDate($new->reg_time);
                $content = "导医登记;由【】更改为【姓名：{$new->name} 手机号：{$new->mobile} 微信号：{$new->wx_name} 生日：{$new->birthday} 年龄：{$new->age} 性别：{$gender} 渠道：{$sourceName} 城市：{$new->city_name} 诊室：{$clinicName} 诊疗号：{$new->patient_card_id} 备注：{$new->remark} 医助：{$belongAssistantName} 就诊类型：{$outpatientName} 初诊日期：{$regTime}】";
                $relationId = $new->id;
                break;
            default:
                break;
        }
        if (empty($content) || empty($type)) {
            return null;
        }
        return self::create($relationId, $content, $type, Yii::$app->user->identity->member_id);
    }

    /**
     * 患者操作
     * @param string $scenario
     * @param User|null $new
     * @param User|null $old
     * @return MemberOperateLog|null
     * @throws \Exception
     */
    public static function createPatientLog(PatientForm $model, ?User $new = null, ?User $old = null, array $params = []): ?MemberOperateLog
    {
        $content = '';
        $type = 0;
        $relationId = 0;
        switch ($model->getScenario()) {
            case 'edit':// 患者编辑
                if (self::isEditModel($new, $old, ['name', 'birthday', 'age', 'nickname', 'mobile', 'wx_name', 'gender', 'source_channel_id', 'city_name', 'address', 'patient_diseases_id', 'patient_diseases_child_id', 'effect_type_id', 'risk_type_id', 'clinic_assess_id', 'outpatient_type_id', 'clinic_id', 'profession', 'belong_assistant_id', 'belong_member_id'])
                    || $model->getAddBodyPartsIds()
                    || $model->getDeleteBodyPartsIds()
                    || $model->getAddTagsIds()
                    || $model->getDeleteTagsIds()
                ) {
                    $type = MemberOperateLog::TYPE_PATIENT_EDIT;
                    // 原信息
                    $oldGender = User::$genders[$old->gender] ?? '';
                    $oldSourceName = $old->source_channel_id ? SourceChannel::findOne($old->source_channel_id)->source_name ?? '' : '';
                    $oldDiseasesName = $old->patient_diseases_id ? PatientDiseases::findOne($old->patient_diseases_id)->diseases_name ?? '' : '';
                    $oldDiseasesChildName = $old->patient_diseases_child_id ? PatientDiseases::findOne($old->patient_diseases_child_id)->diseases_name ?? '' : '';
                    $oldEffectName = $old->effect_type_id ? EffectType::findOne($old->effect_type_id)->effect_name ?? '' : '';
                    $oldRiskName = $old->risk_type_id ? RiskType::findOne($old->risk_type_id)->risk_name ?? '' : '';
                    $oldAssessName = $old->clinic_assess_id ? ClinicAssess::findOne($old->clinic_assess_id)->assess_name ?? '' : '';
                    $oldOutpatientName = $old->outpatient_type_id ? OutpatientType::findOne($old->outpatient_type_id)->outpatient_name ?? '' : '';
                    $oldClinicName = $old->clinic_id ? Clinic::findOne($old->clinic_id)->name ?? '' : '';
                    $oldBelongAssistantName = Member::findOne($old->belong_assistant_id)->realname ?? '';
                    $oldBelongMemberName = Member::findOne($old->belong_member_id)->realname ?? '';
                    $oldStr = "【姓名：{$old->name} 生日：{$old->birthday} 年龄：{$old->age} 微信昵称：{$old->nickname} 微信号：{$old->wx_name} 手机号：{$old->mobile} 性别：{$oldGender} 渠道：{$oldSourceName} 城市：{$old->city_name} 详细地址：{$old->address} 一级病种：{$oldDiseasesName} 二级病种：{$oldDiseasesChildName} 效果类型：{$oldEffectName} 风控类型：{$oldRiskName} 诊疗评估：{$oldAssessName} 就诊类型：{$oldOutpatientName} 诊室：{$oldClinicName} 职业：{$old->profession} 部位：{$old->patient_body_parts_name} 标签：{$old->patient_tags_name} 医助：{$oldBelongAssistantName} 客服：{$oldBelongMemberName}】";
                    // 新信息
                    $newGender = User::$genders[$new->gender] ?? '';
                    $newSourceName = $model->getSourceChannel()->source_name ?? '';
                    $newDiseasesName = $model->getPatientDiseases()->diseases_name ?? '';
                    $newDiseasesChildName = $model->getPatientDiseasesChild()->diseases_name ?? '';
                    $newEffectName = $model->getEffectType()->effect_name ?? '';
                    $newRiskName = $model->getRiskType()->risk_name ?? '';
                    $newAssessName = $model->getClinicAssess()->assess_name ?? '';
                    $newOutpatientName = $model->getOutpatientType()->outpatient_name ?? '';
                    $newClinicName = $model->getClinic()->name ?? '';
                    $newBelongAssistantName = Member::findOne($new->belong_assistant_id)->realname ?? '';
                    $newBelongMemberName = Member::findOne($new->belong_member_id)->realname ?? '';
                    $newStr = "【姓名：{$new->name} 生日：{$new->birthday} 年龄：{$new->age} 微信昵称：{$new->nickname} 微信号：{$new->wx_name} 手机号：{$new->mobile} 性别：{$newGender} 渠道：{$newSourceName} 城市：{$new->city_name} 详细地址：{$new->address} 一级病种：{$newDiseasesName} 二级病种：{$newDiseasesChildName} 效果类型：{$newEffectName} 风控类型：{$newRiskName} 诊疗评估：{$newAssessName} 就诊类型：{$newOutpatientName} 诊室：{$newClinicName} 职业：{$new->profession} 部位：{$new->patient_body_parts_name} 标签：{$new->patient_tags_name} 医助：{$newBelongAssistantName} 客服：{$newBelongMemberName}】";
                    $content = "患者编辑;由{$oldStr}更改为{$newStr}";
                    $relationId = $new->id;
                }
                break;
            case 'edit_remark':// 编辑患者备注
                if (self::isEditModel($new, $old, ['remark'])) {
                    $type = MemberOperateLog::TYPE_PATIENT_EDIT_REMAKR;
                    $content = "患者编辑备注;由【备注：{$old->remark}】更改为【备注：{$new->remark}】";
                    $relationId = $new->id;
                }
                break;
            case 'edit_member_id':// 编辑客服归属人
                if (self::isEditModel($new, $old, ['belong_member_id'])) {
                    $type = MemberOperateLog::TYPE_PATIENT_ALLOT_KF;
                    $content = "患者分配客服;由【客服：{$old->belong_member_name}】更改为【客服：{$new->belong_member_name}】";
                    $relationId = $new->id;
                }
                break;
            case 'edit_batch_member_id':// 批量分配
                $type = MemberOperateLog::TYPE_PATIENT_ALLOT_BATCH;
                $content = $model->check_type == 2 ? '医助分配;【' : '客服分配;【';
                foreach ($params['allot_data'] as $row) {
                    $ids = implode(',', $row['patient_ids']);
                    $content .= "归属人：{$row['member_name']} 患者IDs：{$ids}; ";
                }
                $content .= "】";
                $relationId = 0;
                break;
            default:
                break;
        }
        if (empty($content) || empty($type)) {
            return null;
        }
        return self::create($relationId, $content, $type, Yii::$app->user->identity->member_id);
    }

    /**
     * 患者回访操作
     * @param string $scenario
     * @param Callback $callback
     * @param PatientForm $model
     * @param User $new
     * @param User|null $old
     * @return MemberOperateLog|null
     * @throws \Exception
     */
    public static function createCallbackLog(string $scenario, Callback $callback, PatientForm $model, User $new, ?User $old = null): ?MemberOperateLog
    {
        $content = '';
        $type = 0;
        $relationId = 0;
        switch ($scenario) {
            case 'create':// 新增回访
                $type = MemberOperateLog::TYPE_PATIENT_CALLBACK_CREATE;
                $relationId = $callback->id;
                $callbackWay = Callback::$callbackWayIds[$callback->callback_way_id] ?? '';
                $nextCallbackTime = DateHelper::timestampToDate($callback->next_callback_time);
                $nextFuzhenTime = DateHelper::timestampToDate($callback->next_fuzhen_time);
                $outpatientName = $callback->outpatient_type_id ? OutpatientType::findOne($callback->outpatient_type_id)->outpatient_name ?? '' : '';
                $content = "新增回访;回访内容【回访状态：{$callback->callback_state} 回访方式：{$callbackWay} 内容：{$callback->content} 下次回访：{$nextCallbackTime} 下次复诊：{$nextFuzhenTime} 回访人：{$callback->member_name} 就诊类型：{$outpatientName}】";
                // 患者编辑
                if (self::isEditModel($new, $old, ['kf_last_callback_time', 'kf_next_callback_time', 'kf_callback_count', 'kf_last_callback_user', 'yz_last_callback_time', 'yz_next_callback_time', 'yz_callback_count', 'yz_last_callback_user', 'last_callback_time', 'next_callback_time', 'effect_type_id', 'risk_type_id', 'callback_count', 'next_revisiting_time'])
                    || $model->getAddTagsIds()
                    || $model->getDeleteTagsIds()
                ) {
                    // 原信息
                    $oldLastCallbackTime = DateHelper::timestampToDate($old->last_callback_time);
                    $oldNextCallbackTime = DateHelper::timestampToDate($old->next_callback_time);
                    $oldNextRevisitingTime = DateHelper::timestampToDate($old->next_revisiting_time);
                    $oldEffectName = $old->effect_type_id ? EffectType::findOne($old->effect_type_id)->effect_name ?? '' : '';
                    $oldRiskName = $old->risk_type_id ? RiskType::findOne($old->risk_type_id)->risk_name ?? '' : '';
                    $oldStr = "【上次回访：{$oldLastCallbackTime} 下次回访：{$oldNextCallbackTime} 回访数：{$old->callback_count} 下次复诊：{$oldNextRevisitingTime} 效果类型：{$oldEffectName} 风控类型：{$oldRiskName} 标签：{$old->patient_tags_name}】";
                    // 新信息
                    $newLastCallbackTime = DateHelper::timestampToDate($new->last_callback_time);
                    $newNextCallbackTime = DateHelper::timestampToDate($new->next_callback_time);
                    $newNextRevisitingTime = DateHelper::timestampToDate($new->next_revisiting_time);
                    $newEffectName = $new->effect_type_id ? EffectType::findOne($new->effect_type_id)->effect_name ?? '' : '';
                    $newRiskName = $new->risk_type_id ? RiskType::findOne($new->risk_type_id)->risk_name ?? '' : '';
                    $newStr = "【上次回访：{$newLastCallbackTime} 下次回访：{$newNextCallbackTime} 回访数：{$new->callback_count} 下次复诊：{$newNextRevisitingTime} 效果类型：{$newEffectName} 风控类型：{$newRiskName} 标签：{$new->patient_tags_name}】";
                    $content .= ";患者：{$new->name} 由{$oldStr}更改为{$newStr}";
                }
                break;
            default:
                break;
        }
        if (empty($content) || empty($type)) {
            return null;
        }
        return self::create($relationId, $content, $type, Yii::$app->user->identity->member_id);
    }

    /**
     * 中转库同步日志
     * @param string $scenario
     * @param User $new
     * @param User|null $old
     * @return MemberOperateLog|null
     * @throws \Exception
     */
    public static function createHospitalLog(string $scenario, User $new, ?User $old = null): ?MemberOperateLog
    {
        $content = '';
        $type = 0;
        $relationId = 0;
        switch ($scenario) {
            case 'create':// 中转库新增用户
                if (self::isEditModel($new, $old, ['patient_card_id', 'name', 'birthday', 'age', 'mobile', 'reg_time', 'gender', 'city_name', 'address', 'work_address', 'source_channel_id', 'outpatient_type_id', 'clinic_id', 'yz_next_callback_time', 'belong_assistant_id', 'status', 'serial_no'])) {
                    $type = MemberOperateLog::TYPE_PATIENT_HOSPITAL_CREATE;
                    // 原信息
                    $oldStr = "【】";
                    if ($old && $old->id) {
                        $oldGender = User::$genders[$old->gender] ?? '';
                        $oldRegTime = DateHelper::timestampToDate($old->reg_time);
                        $oldSourceName = $old->source_channel_id ? SourceChannel::findOne($old->source_channel_id)->source_name ?? '' : '';
                        $oldOutpatientName = $old->outpatient_type_id ? OutpatientType::findOne($old->outpatient_type_id)->outpatient_name ?? '' : '';
                        $oldClinicName = $old->clinic_id ? Clinic::findOne($old->clinic_id)->name ?? '' : '';
                        $oldYzNextCallbackTime = DateHelper::timestampToDate($old->yz_next_callback_time);
                        $oldBelongAssistantName = Member::findOne($old->belong_assistant_id)->realname ?? '';
                        $oldStatus = User::$status[$old->status] ?? '';
                        $oldStr = "【姓名：{$old->name} 诊疗号：{$old->patient_card_id} 生日：{$old->birthday} 年龄：{$old->age} 手机号：{$old->mobile} 性别：{$oldGender} 初诊时间：{$oldRegTime} 城市：{$old->city_name} 详细地址：{$old->address} 工作地址：{$old->work_address} 渠道：{$oldSourceName} 就诊类型：{$oldOutpatientName} 诊室：{$oldClinicName} 医助下次回访时间：{$oldYzNextCallbackTime} 医助：{$oldBelongAssistantName} 状态：{$oldStatus} 亦远ID：{$old->serial_no}】";
                    }
                    // 新信息
                    $newGender = User::$genders[$new->gender] ?? '';
                    $newRegTime = DateHelper::timestampToDate($new->reg_time);
                    $newSourceName = $new->source_channel_id ? SourceChannel::findOne($new->source_channel_id)->source_name ?? '' : '';
                    $newOutpatientName = $new->outpatient_type_id ? OutpatientType::findOne($new->outpatient_type_id)->outpatient_name ?? '' : '';
                    $newClinicName = $new->clinic_id ? Clinic::findOne($new->clinic_id)->name ?? '' : '';
                    $newYzNextCallbackTime = DateHelper::timestampToDate($new->yz_next_callback_time);
                    $newBelongAssistantName = Member::findOne($new->belong_assistant_id)->realname ?? '';
                    $newStatus = User::$status[$new->status] ?? '';
                    $newStr = "【姓名：{$new->name} 诊疗号：{$new->patient_card_id} 生日：{$new->birthday} 年龄：{$new->age} 手机号：{$new->mobile} 性别：{$newGender} 初诊时间：{$newRegTime} 城市：{$new->city_name} 详细地址：{$new->address} 工作地址：{$new->work_address} 渠道：{$newSourceName} 就诊类型：{$newOutpatientName} 诊室：{$newClinicName} 医助下次回访时间：{$newYzNextCallbackTime} 医助：{$newBelongAssistantName} 状态：{$newStatus} 亦远ID：{$new->serial_no}】";
                    $content = "中转库新增患者;由{$oldStr}更改为{$newStr}";
                    $relationId = $new->id;
                }
                break;
            case 'update':// 中转库更新用户
                if (self::isEditModel($new, $old, ['patient_card_id', 'name', 'birthday', 'age', 'mobile', 'reg_time', 'gender', 'address', 'status'])) {
                    $type = MemberOperateLog::TYPE_PATIENT_HOSPITAL_CREATE;
                    // 原信息
                    $oldStr = "【】";
                    if ($old && $old->id) {
                        $oldGender = User::$genders[$old->gender] ?? '';
                        $oldRegTime = DateHelper::timestampToDate($old->reg_time);
                        $oldStatus = User::$status[$old->status] ?? '';
                        $oldStr = "【姓名：{$old->name} 诊疗号：{$old->patient_card_id} 生日：{$old->birthday} 年龄：{$old->age} 手机号：{$old->mobile} 性别：{$oldGender} 初诊时间：{$oldRegTime} 详细地址：{$old->address} 状态：{$oldStatus}】";
                    }
                    // 新信息
                    $newGender = User::$genders[$new->gender] ?? '';
                    $newRegTime = DateHelper::timestampToDate($new->reg_time);
                    $newStatus = User::$status[$new->status] ?? '';
                    $newStr = "【姓名：{$new->name} 诊疗号：{$new->patient_card_id} 生日：{$new->birthday} 年龄：{$new->age} 手机号：{$new->mobile} 性别：{$newGender} 初诊时间：{$newRegTime} 详细地址：{$new->address} 状态：{$newStatus}】";
                    $content = "中转库更新患者;由{$oldStr}更改为{$newStr}";
                    $relationId = $new->id;
                }
                break;
            default:
                break;
        }
        if (empty($content) || empty($type)) {
            return null;
        }
        return self::create($relationId, $content, $type);
    }
}
